package cn.kgm.core.utils;

import cn.hutool.core.text.CharSequenceUtil;
import cn.kgm.core.constant.StrPool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Objects;
import java.util.Optional;

/**
 * 错误信息处理类。
 *
 * @author kappi
 */
@Slf4j
public class ExceptionUtil
{
    /**
     * 获取exception的详细错误信息。
     * 输出此信息的效果等于调用该异常的printStackTrace()方法
     */
    public static String getExceptionMessage(Throwable e)
    {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw, true));
        return sw.toString();
    }

    /**
     * 获取异常的message信息
     *
     * @param e 异常主体
     * @return 异常的message信息
     */
    public static String getRootErrorMessage(Exception e)
    {
        String msg = StrPool.EMPTY;
        Throwable root = ExceptionUtils.getRootCause(e);
        root = Optional.ofNullable(root).orElse(e);
        if (Objects.nonNull(root)){
            msg = root.getMessage();
        }
        msg = CharSequenceUtil.nullToDefault(msg, StrPool.NULL);
        return StringUtils.defaultString(msg);
    }

    /**
     * 使用环境：当被抛出异常方法不因为此异常而中断程序时使用
     * 格式化输出异常信息
     *
     * @author kappi
     */
    public static void format(Throwable e, Class<?> o) {
        Throwable throwable = Optional.ofNullable(e.getCause()).orElse(e);
        Optional.ofNullable(throwable)
                .map(Throwable::getStackTrace)
                .ifPresent(stacks -> {
                    for (StackTraceElement stack : stacks) {
                        if (stack.getClassName().equals(o.getName())) {
                            log.error("【{}】::【{}】::line=>【{}】", stack.getClassName(), stack.getMethodName(), stack.getLineNumber());
                            log.error("eMsg=>【{}】,eName=>【{}】", throwable.getMessage(), throwable.getClass().getName());
                            return;
                        }
                    }
                });
    }
}
